﻿using AntdUI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VSTOWord.Helpers;

namespace VSTOWord
{
    public partial class FrmImageViewer : Window
    {
        private float zoomFactor = 1.0f; // 缩放比例
        private const float zoomStep = 0.1f; // 每次滚轮滚动的缩放步长
        private const float minZoom = 0.1f; // 最小缩放比例
        private const float maxZoom = 5.0f; // 最大缩放比例
        private Image originalImage; // 保存原始图片

        // 拖动相关变量
        private bool isDragging = false;
        private Point lastMousePosition;

        public FrmImageViewer(Image image)
        {
            InitializeComponent();

            this.Size = new Size(1300, 900);

            //保存原始图片
            originalImage = image;

            //设置图片
            pic.Image = image;

            //订阅鼠标滚轮事件
            //pic.MouseWheel += Pic_MouseWheel;
            panel1.MouseWheel += Panel1_MouseWheel;

            //订阅鼠标拖动事件
            panel1.MouseDown += Panel1_MouseDown;
            panel1.MouseMove += Panel1_MouseMove;
            panel1.MouseUp += Panel1_MouseUp;
            pic.MouseDown += Pic_MouseDown;
            pic.MouseMove += Pic_MouseMove;
            pic.MouseUp += Pic_MouseUp;

            //订阅窗体加载事件以居中图片
            this.Load += FrmImageViewer_Load;

            //订阅窗体大小变化事件
            this.Resize += FrmImageViewer_Resize;

            //设置主题
            ThemeHelper.SetColorMode(this, false);

            this.pageHeader1.Text = $"图片预览 - {GlobalHelper.Version} (缩放: 100%)";
            this.pageHeader1.Size = new Size(this.Width, 35);
        }
        private void FrmImageViewer_Load(object sender, EventArgs e)
        {
            // 窗体加载完成后自动适配图片大小
            AutoFitImage();
        }

        private void FrmImageViewer_Resize(object sender, EventArgs e)
        {
            // 窗体大小变化时重新适配图片
            if (originalImage != null && this.WindowState != FormWindowState.Minimized)
            {
                AutoFitImage();
            }
        }

        private void AutoFitImage()
        {
            if (originalImage == null) return;

            // 获取面板的可用空间（减去 Padding）
            int availableWidth = panel1.ClientSize.Width - panel1.Padding.Left - panel1.Padding.Right;
            int availableHeight = panel1.ClientSize.Height - panel1.Padding.Top - panel1.Padding.Bottom;

            // 计算缩放比例以适应面板
            float scaleWidth = (float)availableWidth / originalImage.Width;
            float scaleHeight = (float)availableHeight / originalImage.Height;

            // 如果图片小于面板，保持原始大小（100%）
            // 如果图片大于面板，按比例缩小以适应面板
            if (originalImage.Width <= availableWidth && originalImage.Height <= availableHeight)
            {
                // 图片小于面板，保持原始大小
                zoomFactor = 1.0f;
            }
            else
            {
                // 图片大于面板，选择较小的缩放比例以确保完整显示
                zoomFactor = Math.Min(scaleWidth, scaleHeight);
                // 确保缩放比例在允许范围内
                zoomFactor = Math.Max(minZoom, Math.Min(maxZoom, zoomFactor));
            }

            // 应用缩放
            ApplyZoom(0.5f, 0.5f);

            // 更新标题显示当前缩放比例
            this.pageHeader1.Text = $"图片预览 - {GlobalHelper.Version} (缩放: {(int)(zoomFactor * 100)}%)";
        }
        private void Pic_MouseWheel(object sender, MouseEventArgs e)
        {
            HandleMouseWheel(e);
        }

        private void Panel1_MouseWheel(object sender, MouseEventArgs e)
        {
            HandleMouseWheel(e);
        }

        private void HandleMouseWheel(MouseEventArgs e)
        {
            float oldZoom = zoomFactor;
            
            // 计算新的缩放比例
            if (e.Delta > 0)
            {
                // 向上滚动，放大
                zoomFactor = Math.Min(zoomFactor + zoomStep, maxZoom);
            }
            else
            {
                // 向下滚动，缩小
                zoomFactor = Math.Max(zoomFactor - zoomStep, minZoom);
            }

            // 如果缩放比例没有变化，直接返回
            if (Math.Abs(oldZoom - zoomFactor) < 0.001f)
                return;

            // 获取鼠标在 PictureBox 中的相对位置
            Point mousePos = pic.PointToClient(Control.MousePosition);
            
            // 计算鼠标位置相对于图片的比例
            float mouseXRatio = (float)mousePos.X / pic.Width;
            float mouseYRatio = (float)mousePos.Y / pic.Height;

            // 应用缩放
            ApplyZoom(mouseXRatio, mouseYRatio);

            // 更新标题显示当前缩放比例
            this.pageHeader1.Text = $"图片预览 - {GlobalHelper.Version} (缩放: {(int)(zoomFactor * 100)}%)";
        }

        private void ApplyZoom(float mouseXRatio = 0.5f, float mouseYRatio = 0.5f)
        {
            if (originalImage == null) return;

            // 保存旧的尺寸和位置
            int oldWidth = pic.Width;
            int oldHeight = pic.Height;
            int oldLeft = pic.Left;
            int oldTop = pic.Top;

            // 计算新的尺寸
            int newWidth = (int)(originalImage.Width * zoomFactor);
            int newHeight = (int)(originalImage.Height * zoomFactor);

            // 创建缩放后的图片
            Bitmap scaledImage = new Bitmap(newWidth, newHeight);
            using (Graphics g = Graphics.FromImage(scaledImage))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.DrawImage(originalImage, 0, 0, newWidth, newHeight);
            }

            pic.Image = scaledImage;
            pic.SizeMode = PictureBoxSizeMode.AutoSize;

            // 根据鼠标位置调整图片位置，使缩放以鼠标为中心
            if (oldWidth > 0 && oldHeight > 0)
            {
                // 计算鼠标在旧图片中的绝对位置
                int mouseXInOldImage = (int)(oldWidth * mouseXRatio);
                int mouseYInOldImage = (int)(oldHeight * mouseYRatio);

                // 计算鼠标在新图片中应该在的位置
                int mouseXInNewImage = (int)(newWidth * mouseXRatio);
                int mouseYInNewImage = (int)(newHeight * mouseYRatio);

                // 计算新的 PictureBox 位置
                pic.Left = oldLeft + (mouseXInOldImage - mouseXInNewImage);
                pic.Top = oldTop + (mouseYInOldImage - mouseYInNewImage);
            }

            // 限制边界
            ConstrainBounds();
        }

        private void ConstrainBounds()
        {
            // 如果图片小于面板，居中显示
            if (pic.Width <= panel1.ClientSize.Width)
            {
                pic.Left = (panel1.ClientSize.Width - pic.Width) / 2;
            }
            else
            {
                // 图片宽度大于面板，限制左右边界
                // 不允许左边界超出太多（图片右侧必须可见）
                int maxLeft = 0;
                int minLeft = panel1.ClientSize.Width - pic.Width;
                pic.Left = Math.Max(minLeft, Math.Min(maxLeft, pic.Left));
            }

            if (pic.Height <= panel1.ClientSize.Height)
            {
                pic.Top = (panel1.ClientSize.Height - pic.Height) / 2;
            }
            else
            {
                // 图片高度大于面板，限制上下边界
                // 不允许上边界超出太多（图片底部必须可见）
                int maxTop = 0;
                int minTop = panel1.ClientSize.Height - pic.Height;
                pic.Top = Math.Max(minTop, Math.Min(maxTop, pic.Top));
            }
        }

        // Panel 鼠标按下事件
        private void Panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && zoomFactor > 1.0f)
            {
                isDragging = true;
                lastMousePosition = e.Location;
                panel1.Cursor = Cursors.Hand;
            }
        }

        // Panel 鼠标移动事件
        private void Panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                // 计算鼠标移动的距离
                int deltaX = e.X - lastMousePosition.X;
                int deltaY = e.Y - lastMousePosition.Y;

                // 计算新位置
                int newLeft = pic.Left + deltaX;
                int newTop = pic.Top + deltaY;

                // 应用边界限制
                if (pic.Width <= panel1.ClientSize.Width)
                {
                    newLeft = (panel1.ClientSize.Width - pic.Width) / 2;
                }
                else
                {
                    int maxLeft = 0;
                    int minLeft = panel1.ClientSize.Width - pic.Width;
                    newLeft = Math.Max(minLeft, Math.Min(maxLeft, newLeft));
                }

                if (pic.Height <= panel1.ClientSize.Height)
                {
                    newTop = (panel1.ClientSize.Height - pic.Height) / 2;
                }
                else
                {
                    int maxTop = 0;
                    int minTop = panel1.ClientSize.Height - pic.Height;
                    newTop = Math.Max(minTop, Math.Min(maxTop, newTop));
                }

                // 设置位置
                pic.Left = newLeft;
                pic.Top = newTop;

                // 只在实际移动时更新鼠标位置
                lastMousePosition = e.Location;
            }
            else if (zoomFactor > 1.0f)
            {
                panel1.Cursor = Cursors.Hand;
            }
            else
            {
                panel1.Cursor = Cursors.Default;
            }
        }

        // Panel 鼠标释放事件
        private void Panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isDragging = false;
                panel1.Cursor = zoomFactor > 1.0f ? Cursors.Hand : Cursors.Default;
            }
        }

        // PictureBox 鼠标按下事件
        private void Pic_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isDragging = true;
                // 转换为 Panel 坐标系
                lastMousePosition = panel1.PointToClient(pic.PointToScreen(e.Location));
                pic.Cursor = Cursors.Hand;
            }
        }

        // PictureBox 鼠标移动事件
        private void Pic_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                // 转换为 Panel 坐标系
                Point currentPosition = panel1.PointToClient(pic.PointToScreen(e.Location));
                
                // 计算鼠标移动的距离
                int deltaX = currentPosition.X - lastMousePosition.X;
                int deltaY = currentPosition.Y - lastMousePosition.Y;

                // 计算新位置
                int newLeft = pic.Left + deltaX;
                int newTop = pic.Top + deltaY;

                // 应用边界限制
                if (pic.Width <= panel1.ClientSize.Width)
                {
                    newLeft = (panel1.ClientSize.Width - pic.Width) / 2;
                }
                else
                {
                    int maxLeft = 0;
                    int minLeft = panel1.ClientSize.Width - pic.Width;
                    newLeft = Math.Max(minLeft, Math.Min(maxLeft, newLeft));
                }

                if (pic.Height <= panel1.ClientSize.Height)
                {
                    newTop = (panel1.ClientSize.Height - pic.Height) / 2;
                }
                else
                {
                    int maxTop = 0;
                    int minTop = panel1.ClientSize.Height - pic.Height;
                    newTop = Math.Max(minTop, Math.Min(maxTop, newTop));
                }

                // 设置位置
                pic.Left = newLeft;
                pic.Top = newTop;

                // 更新鼠标位置
                lastMousePosition = currentPosition;
            }
            else if (zoomFactor > 1.0f)
            {
                pic.Cursor = Cursors.Hand;
            }
            else
            {
                pic.Cursor = Cursors.Default;
            }
        }

        // PictureBox 鼠标释放事件
        private void Pic_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isDragging = false;
                pic.Cursor = zoomFactor > 1.0f ? Cursors.Hand : Cursors.Default;
            }
        }

        

        private void FrmImageViewer_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.Close();
            }
        }
    }
}
